package com.generator.mybatisplus;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ToStringExclude;
import org.assertj.core.util.Lists;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.junit.jupiter.api.Test;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.DayOfWeek;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.time.temporal.TemporalAdjusters;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

public class Ax {

    @Test
    public void cc () {
        //1.BigDecimal 转换成字符串 1保留小数后的0 2不保留 3
        BigDecimal a = new BigDecimal("100.1500");
        System.out.println(a.toPlainString());
        String s = a.stripTrailingZeros().toPlainString();
        System.out.println(s);
        DecimalFormat decimalFormat = new DecimalFormat("0.0");
        //1-3自定义保留小数位数(四舍五入
        System.out.println(decimalFormat.format(a));
        //2.字符串保留10位如果最后一位是',号' 删除
        String cs = "1,3,4,5,11";
        if (cs.length() > 10) {
            cs = cs.substring(0, cs.substring(0, 10).lastIndexOf(","));
        }
        System.out.println(cs);
    }

    @Test
    public void hehe () {
        //1.获取昨天 当前对应时间
        DateTime yesterday = DateUtil.yesterday();
        System.out.println(DateUtil.formatDateTime(yesterday));
        DateTime date = DateUtil.date();
        System.out.println(DateUtil.formatDateTime(date));
        //时间减去一天
        System.out.println(DateUtil.offsetDay(date, -1));
        String s = "12";
        System.out.println(s.concat("_").concat("ull"));
    }

    @Test
    public void cs() {
        ArrayList<String> list = null;
//        list.add("cs");
        ArrayList<String> strings = Optional.ofNullable(list).orElse(CollUtil.newArrayList("a"));
        System.out.println(strings);
        String str = "123c.xcsds.xl  12\n\r12";
        //1获取文件后缀
        String substring = str.substring(str.lastIndexOf(".") + 1);
        //2去除字符串中的 回车空格
        String s = StringUtils.deleteWhitespace(str);
        System.out.println("rr:" +s);
        System.out.println("rr:" +str);
//        System.out.println(str.lastIndexOf("."));
        System.out.println(substring);
        String fullClassName = ")学界(j)";
        int i = fullClassName.indexOf(")");
        if (i != -1) {
            System.out.println(fullClassName.substring(i+1));
            System.out.println(fullClassName.substring(0, i+1));
        }
    }



    @Test
    public void csDate1(){
        DateTime date = DateUtil.date();
        //1 日期1昨天时间 2获取昨天上周当前时间
        Date yesterday = DateUtil.yesterday();
        DateTime lastWeek = DateUtil.lastWeek();
        DateTime dateTime = DateUtil.offsetDay(lastWeek, 1);
        System.out.println(DateUtil.format(date, "yyyy-MM-dd HH:mm:ss"));
        System.out.println(DateUtil.format(dateTime, "yyyy-MM-dd HH:mm:ss"));
        //2当前时间(不含时分秒) 1当前时间减一天 2 当前时间加一天
        LocalDate yearEndDate = LocalDate.now();
        System.out.println(yearEndDate.minusDays(1));
        System.out.println(yearEndDate.plusDays(1));
        //2-3 日期对比 =0相等 >0大于 <0小于
        System.out.println((yearEndDate.plusDays(5).compareTo(yearEndDate.plusDays(1))));
    }
    @Test
    public void csDate2() throws ParseException {
        String s = "7:50:20";
        s = "2023-08-10 " + s;
        //1日期格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        Date parse = sdf.parse(s);
        System.out.println(DateUtil.formatDateTime(parse));
        //2Optional断言使用,当前条件不为空
        String c = "";
        String o = Optional.ofNullable(c).orElse("12");
        System.err.println(o);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-M-d HH:mm");
        System.out.println("2024年8".matches("\\d{4}(-|年)\\d{1,2}(-\\d{1,2})?( \\d{1,2}(:\\d{1,2})?(:\\d{1,2})?)?$"));

        System.out.println("1234".matches("[1-9][0-9]{4,}"));
        LocalDate of = LocalDate.of(2025, 1, 3);
        LocalDate of1 = LocalDate.of(2024, 1, 3);

        System.out.println(ChronoUnit.DAYS.between(of1, of));

    }
    @Test
    public void csDate3() {
        String s = "11:50:20";
        s = "2023-08-15 " + s;
        Date dateTime = DateUtil.parseDateTime(s);
        //课程开始时间
        long createTime = dateTime.getTime();
        //当前时间
        long currentTime = Date.from(Instant.now()).getTime();
        System.out.println(DateUtil.formatDateTime(dateTime));
        System.out.println(DateUtil.formatDateTime(Date.from(Instant.now())));
        //1比较时间 与当前时间 差多少分钟
        long diff=(createTime - currentTime)/1000/60;
        System.out.println(diff);
        if (diff > 30) {

        }
    }

    @Test
    public void csDate4() {
        //1获取上个月 这周开始时间
        LocalDateTime lastWeekStart = LocalDateTime.now().minusMonths(1).with(DayOfWeek.MONDAY);
        System.out.println(lastWeekStart);
        Calendar start = Calendar.getInstance();
        start.setTime(DateUtil.date());
        start.set(Calendar.DAY_OF_WEEK, 2);//设置为本周第一天(星期一
        System.out.println(DateUtil.formatDateTime(start.getTime()));
        System.out.println(start.getActualMaximum(Calendar.DAY_OF_WEEK));
        //2获取 最后一天, 不同最后一天是星期六
        start.set(Calendar.DAY_OF_WEEK, start.getActualMaximum(Calendar.DAY_OF_WEEK));
        //2-2日期加1(就得到星期天
        start.add(Calendar.DAY_OF_WEEK, 1);
        System.out.println(DateUtil.formatDateTime(start.getTime()));
        //3比较日期 忽悠时分秒(不包含
        LocalDate now = LocalDate.now();
        start.add(Calendar.DAY_OF_WEEK, -5);
        //3-2 date转换为LocalDate 比较
        LocalDate of = start.getTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
        System.out.println(of.isAfter(now));
        System.out.println(LocalDate.now().compareTo(LocalDate.now()));
    }

    @Test
    public void csDate5() {
        Calendar start = Calendar.getInstance();
        start.setTime(DateUtil.date());
        //1日期设置为本周2
        start.set(Calendar.DAY_OF_WEEK, 3);
        System.out.println(DateUtil.formatDateTime(start.getTime()));
        //1-2 获取当前是周几
        System.out.println(start.get(Calendar.DAY_OF_WEEK));
        String tableId = "1,2";
        Integer one = 1;
        if (one.equals(null)) {
            System.out.println(tableId.substring(0, tableId.indexOf(",") + 1));
        }
        LocalDate birthdate = LocalDate.parse("2024-6-25", DateTimeFormatter.ofPattern("yyyy-M-d"));
        //相差多少周 2相差多少月
        int between = (int)ChronoUnit.WEEKS.between(birthdate, LocalDate.now());
        int between2 = (int)ChronoUnit.MONTHS.between(birthdate, LocalDate.now());

        System.out.println("相差天:"+ChronoUnit.DAYS.between(birthdate, LocalDate.now()));
        System.out.println("相差周:"+between);
        System.out.println("相差月:"+between2);
        System.out.println("当前月:"+ LocalDate.of(2024, 2, 29).withMonth(LocalDate.now().getMonthValue()).withYear(LocalDate.now().getYear()));
        System.out.println("2月:"+ LocalDate.of(2024, 2, 29).withMonth(2).withYear(LocalDate.now().getYear()));
        System.out.println("周:"+  LocalDate.now()
                .with(TemporalAdjusters.previousOrSame(birthdate.getDayOfWeek())));


        Period period = Period.between(birthdate, LocalDate.now());
        int i = period.getYears() * 12 + period.getMonths();
        System.out.println(i);
        LocalDateTime dateTime1 = LocalDateTime.now().plusMinutes(60);
        LocalDateTime dateTime = dateTime1.withMinute(0).withSecond(0).withNano(0);
        System.out.println(dateTime1);
        System.out.println(dateTime);
        LocalTime of = LocalTime.of(23, 49);
        System.out.println(of.plusMinutes(10).compareTo(of));

    }
    //计算生日
    @Test
    public void csDate6() {
        LocalDate birthday = LocalDate.of(1990, 5, 17); // 示例生日日期
        LocalDate today = LocalDate.now(); // 当前日期

        // 计算今年过生日还有多少天
        LocalDate thisYearBirthday = LocalDate.of(today.getYear(), birthday.getMonth(), birthday.getDayOfMonth());
        long daysThisYear = ChronoUnit.DAYS.between(today, thisYearBirthday);

        // 如果今天是生日，则天数为0
        if (today.isAfter(thisYearBirthday)) {
            System.out.println("It's your birthday today!");
        } else {
            System.out.println("Days to your birthday this year: " + daysThisYear);
        }

        // 计算下一个生日还有多少天
        LocalDate nextYearBirthday = LocalDate.of(today.getYear() + 1, birthday.getMonth(), birthday.getDayOfMonth());
        long daysNextYear = ChronoUnit.DAYS.between(today, nextYearBirthday);

        System.out.println("Days to your birthday next year: " + daysNextYear);
        System.out.println(DateTimeFormatter.ofPattern("M月d日").format(birthday));

        // 创建两个LocalTime实例
        LocalTime startTime = LocalTime.of(15, 30); // 例如，14:30
        LocalTime endTime = LocalTime.of(15, 15); // 例如，15:15

        // 计算时间差
        Duration duration = Duration.between(startTime, endTime);

        // 转换为分钟
        long minutes = duration.toMinutes(); // 直接使用toMinutes()方法
        // 或者使用纳秒转换：long minutes = duration.toNanos() / 60_000_000_000;

        System.out.println("时间差为：" + minutes + "分钟");

    }
    @Test
    public void csDate7() {
        int len = 10*7;
        StringBuffer sb = new StringBuffer();
        for(int i=0;i<len;i++) {
            sb.append(i%2 == 0?"1":"0");//有课则为1
        }
        String all = sb.toString();
        System.out.println(Long.parseLong("1111111111111111111111111111111111111111111111111111111111111111",2));
        LocalDateTime dateTime1 = LocalDateTime.of(2025, 2, 15, 10, 0);
        LocalDateTime dateTime2 = LocalDateTime.of(2025, 3, 15, 10, 0);

        long monthsBetween = ChronoUnit.MONTHS.between(dateTime1.toLocalDate(), dateTime2.toLocalDate());
        System.out.println("相差的月份数: " + monthsBetween);
    }

    @Test
    public void csString () {
        //1.驼峰转换为->下划线
        System.out.println("userId".replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase());
        System.out.println("USREID".replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase());
        System.out.println("user_id".replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase());
        //2.16进制转换为10进制
        String cardNumTen = new BigInteger("3E41D59", 16).toString(10);
        int length = cardNumTen.length();
        //2-2 循环补0
        if (length < 10) {
            // 可能长度不是10位数，那就在前补0
            for (int i = 0; i < 10 - length; i++) {
                cardNumTen = "0".concat(cardNumTen);
            }
        }
        //2-3.1format自动补零 2org.apache.commons.lang3下的StringUtils 自动补
        String format = String.format("%010d", Integer.parseInt(cardNumTen));
        String s = StringUtils.leftPad(cardNumTen, 10, '0');
        System.out.println(cardNumTen);
        System.out.println(format);
        System.out.println(s);
        String fileUrl = "http://work.lepayedu.com:28201/group1/M00/0E/34/wKgA7WbNmOuABmdeAAxddl9P90c818.pdf";
        System.out.println(fileUrl.substring(fileUrl.lastIndexOf(".")));
    }

    @Test
    public void csString2() {
        String cardNumTen = new BigInteger("3725152", 16).toString(10);
        int length = cardNumTen.length();
        if (length < 10) {
            // 可能长度不是10位数，那就在前补0
            for (int i = 0; i < 10 - length; i++) {
                cardNumTen = "0".concat(cardNumTen);
            }
        }
        System.out.println(cardNumTen);
        //去除掉 特殊字符,excel名称
        System.out.println("sds|bf/?？：:[]]*/>\\*".replaceAll("\n|\r|/|\\?|？|：|:|\\*|]|\\[|\\\\", ""));
        ArrayList<String> units = Lists.newArrayList("千克", "公斤", null);
        System.out.println(units.contains(null));

        Pattern pattern = Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^&*()_+=\\[{\\]}\\\\|;:'\"\\\\,.<>/?~`-]).+$");;
        Matcher matcher = pattern.matcher("Ad112411*");
        System.out.println(matcher.matches());
    }

    @Test
    public void csString3 () {
        //18702599012
        String phoneNumber = "02818702599012-851";
        int i = phoneNumber.indexOf("-") + 3;
        System.out.println(desensitizationNum(phoneNumber, i, 4, 4));
        String url ="http://118.123.247.216:8111";
        String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
        Pattern pattern = Pattern.compile(regex);
        System.out.println( pattern.matcher(url).matches());
        System.out.println("https://192.168.0.188/cms/file/play?params=CDno6p0Hd5p4xOK60jr1TcA5gVJlIMWjDNsNmKx1MyqO3Zl8xjqplAWr0yoHdz3FbSK2snMC7z9A6OjePhw1gHKVXB6Id2ku7clCqXqNcaxWJU9DpwS%2BMDtyueQJRCpg".length());
    }

    @Test
    public void csString4() {
        String token = "schasdsi---ssds---";
        int i = token.lastIndexOf("---");
        String tokenData = token.substring(0, i);
        String tokenTime = token.substring(i+3);
        System.out.println( tokenData);
        System.out.println( tokenTime);
    }

    final String asterisks = "**********************************************************";
    /**
     * <p>自定义脱敏</p>
     * @author tiku
     * @Date 2025/1/10
     * @param plainMobile
     * @param maxStart 起始明文最大保留数
     * @param maxEnd 末尾明文最大保留数
     * @param min 最少脱敏数
     * @return java.lang.String
     */
    private String desensitizationNum(String plainMobile, int maxStart, int maxEnd, int min) {
        int start = 0, last = 0;
        //获取明文前后各保留位数
        if (plainMobile.length() > min) {
            int i1 = (plainMobile.length() - min) / 2;
            start = Math.max(1, Math.min(i1, maxStart));
            if (i1 > 0) {
                last = Math.min(i1 + (plainMobile.length()%2), maxEnd);
            }
        }
        String asterisk = asterisks.substring(0, Math.min((plainMobile.length() - start - start), asterisks.length()));
        String masked = plainMobile.substring(0, start) + asterisk + plainMobile.substring(plainMobile.length() - last);
        return masked;
    }

    private static double EARTH_RADIUS = 6378138.0;
    private static final double EARTH_RADIUS_KM = 6371.0;
    @Test
    public void cs11() {
        double lat1 =  104.063043;
        double lon1 =  30.665591;
        double lat2 = 104.073104;
        double lon2 =  30.663463;
        // 将经纬度转换为弧度
        double lat1Rad = Math.toRadians(lat1);
        double lon1Rad = Math.toRadians(lon1);
        double lat2Rad = Math.toRadians(lat2);
        double lon2Rad = Math.toRadians(lon2);

        //方式一
        double deltaLat = lat2Rad - lat1Rad;
        double deltaLon = lon2Rad - lon1Rad;
        double a = Math.pow(Math.sin(deltaLat / 2), 2) +
                Math.cos(lat1Rad) * Math.cos(lat2Rad) *
                        Math.pow(Math.sin(deltaLon / 2), 2);
        double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
        double distance = EARTH_RADIUS_KM * c;
        System.err.println(distance);
        System.err.println(distance > 30);

        //方式二
        double radLat1 = rad(lat1);
        double radLat2 = rad(lat2);
        double a1 = radLat1 - radLat2;
        double b = rad(lon1) - rad(lon2);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a1 / 2), 2) +
                Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        System.out.println(s);
        //方式三
        /* 需要添加依赖  https://blog.csdn.net/xyhwork/article/details/119112048
        *   <dependency>
                <groupId>org.gavaghan</groupId>
                <artifactId>geodesy</artifactId>
                <version>1.1.3</version>
            </dependency>
        * */
        GlobalCoordinates source =new GlobalCoordinates(lat1, lon1);
        GlobalCoordinates target =new GlobalCoordinates(lat2, lon2);

        double meter1 = getDistanceMeter(source, target, Ellipsoid.Sphere);
        double meter2 = getDistanceMeter(source, target, Ellipsoid.WGS84);
        System.out.println("Sphere坐标系计算结果："+meter1 +"米");
        System.out.println("WGS84坐标系计算结果："+meter2 +"米");

    }

    public static double getDistanceMeter(GlobalCoordinates gpsFrom, GlobalCoordinates gpsTo, Ellipsoid ellipsoid)
    {
        //创建GeodeticCalculator，调用计算方法，传入坐标系、经纬度用于计算距离
        GeodeticCurve geoCurve =new GeodeticCalculator().calculateGeodeticCurve(ellipsoid, gpsFrom, gpsTo);
        return geoCurve.getEllipsoidalDistance();
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }
    @Test
    public void csStream1() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-15")));
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-14")));
        //1.按日期排序 相同id 取最新的日期数据
        userList = userList.stream().sorted(Comparator.comparing(SchCourseAttendApi::getCreateTime).reversed())
                .collect(Collectors.toList());
        userList = userList.stream().collect(Collectors.toMap(SchCourseAttendApi::getUserId, v -> v, (v1, v2) -> v1)).values().stream().collect(Collectors.toList());
        System.out.println(userList);
    }
    @Test
    public void csStream2() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-14")));
        //1.取出id等于1的第一条数据,不存在返回null
        SchCourseAttendApi schCourseAttendApi = userList.stream().filter(e -> "1".contains(e.getUserId())).findFirst().orElse(null);
        System.out.println(schCourseAttendApi);
        //2.字符串转换为LocalTime
        String timeString = "09:55";
        LocalTime time = LocalTime.parse(timeString);
        LocalTime time2 =  LocalTime.now();
        System.out.println("字符串转LocalTime: " + time);
        System.out.println("当前时间: " + time2);
        System.out.println(time2.compareTo(time));
    }


    @Test
    public void csStream3() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", null));
        //1.取出id符合条件的第一条数据,不存在返回null,存在设置日期 ->不使用orElse 直接用get 不存在会报错
        SchCourseAttendApi schCourseAttendApi = userList.stream().filter(e -> e.getUserId().equals("3")).findFirst().orElse(null);
        System.out.println(userList);
        if (schCourseAttendApi != null) {
            schCourseAttendApi.setCreateTime(DateUtil.parseDate("2023-08-15"));
            System.out.println(userList);
        }
    }

    @Test
    public void cas() {
        BigDecimal a = new BigDecimal("-100011.101");
        String s = a.toPlainString();
        System.out.println(s);
        String filterName ="12112.122";
        //1.判断是否是整数 2判断数字是否4位以上整数 3
        System.out.println(filterName.matches("[0-9]+"));
        System.out.println(filterName.matches("\\d{4,}"));
        System.out.println(filterName.matches("\\d+(\\.\\d{1,2})?"));
        //2.小数位数
        System.out.println(a.scale());
        //3.整数位数(去掉负号
        System.out.println(a.toBigInteger().toString().replace("-", "").length());
//        List<String> classIds = new ArrayList<>();
//        System.out.println(String.join(",", classIds));
//        String originalFilename = "wd.ds.xlsx";
//        System.out.println(originalFilename.lastIndexOf("."));
//        String substring = originalFilename.substring(originalFilename.lastIndexOf(".")+1);
//        System.out.println(substring);
        /*
         */

    }

    @Test
    public void csStreamOrder1() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("33", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("3", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("11", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("1", DateUtil.parseDate("2023-08-13")));
        //1按集合顺序排序
        List<String> orderList = CollUtil.newArrayList("1", "33", "3", "1");
        List<SchCourseAttendApi> collect = userList.stream()
                .sorted(Comparator.comparing((SchCourseAttendApi entity) -> orderList.indexOf(entity.getUserId()))
                        .thenComparing(entity -> userList.indexOf(entity)))
                .collect(Collectors.toList());
        System.out.println(userList);
        System.out.println("---------------------------");
        System.out.println(collect);
        List<Integer> numbers = Arrays.asList(0, 5, 2, 9, 3, 7, -3, -1); // 原始数据列表
        Integer integer = numbers.stream().max(Comparator.comparing(e -> e)).get();
        List<Integer> sortedNumbers = numbers.stream()
//                .sorted(Comparator.comparing(e -> e < 0 ? (integer - e) : e)) // 按照元素的值从小到大排序
                .sorted(Comparator.comparing(e -> e)) // 按照元素的值从小到大排序
                .collect(Collectors.toList());

        System.out.println("排序前：" + numbers);
        System.out.println("排序后：" + sortedNumbers);
        //验证重复
        Set<Map.Entry<String, List<SchCourseAttendApi>>> entries = userList.stream().collect(Collectors.groupingBy(e -> e.getUserId())).entrySet();
        Set<Map.Entry<String, List<String>>> entries1 = userList.stream().map(SchCourseAttendApi::getUserId)
                .collect(Collectors.groupingBy(e -> e)).entrySet();
        boolean b = userList.stream().collect(Collectors.groupingBy(e -> e.getUserId())).entrySet()
                .stream().anyMatch(e -> e.getValue().size() > 1);
        System.out.println(b);
    }

    @Test
    public void csStreamOrder2() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("33", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("3", DateUtil.parseDate("2023-08-14")));
        userList.add(new SchCourseAttendApi("11", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", DateUtil.parseDate("2023-08-13")));
        userList.add(new SchCourseAttendApi("2", null));
        //1.获取id最小的
        SchCourseAttendApi min = userList.stream().min(Comparator.comparing(e -> Integer.parseInt(e.getUserId()), Comparator.nullsFirst(Integer::compareTo))).get();
        SchCourseAttendApi min2 = userList.stream().min(Comparator.comparing(e -> e.getUserId(), Comparator.nullsFirst(String::compareTo))).get();
        if (min2 != null && min != null) {

        }
        SchCourseAttendApi api = userList.stream().filter(e -> e.getUserId().equals("2")).findFirst().orElse(null);
        if (api != null) {

        }
        //取重复数据
        Set<String> collect = userList.stream()
                .collect(Collectors.groupingBy(SchCourseAttendApi::getUserId, Collectors.counting())) // 按名字分组并计数
                .entrySet().stream()
                .filter(entry -> entry.getValue() > 1) // 过滤出计数大于1的条目
                .map(entry -> entry.getKey()) // 获取重复的名字
                .collect(Collectors.toSet());// 转换为Set去除重复
        if (collect != null) {

        }
        //去重
        ArrayList<SchCourseAttendApi> collect1 = userList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() ->
                new TreeSet<>(Comparator.comparing(e -> e.getUserId() + "_" +
                        e.getCreateTime()))), ArrayList::new));
        if (collect1 != null) {

        }
    }

    @Test
    public void csStreamOrder3() {
        List<Education> list = CollUtil.newArrayList();
        list.add(new Education("学校1", "2024.06.17"));
        list.add(new Education("学校2", "2023.12.17"));
        list.add(new Education("学校3", "2024.7.01"));
        list.add(new Education("学校4", ""));
        list.add(new Education("学校5", null));
        Set<String> collect2 = list.stream().map(e -> e.getEndDate()).collect(Collectors.toSet());
        System.out.println(collect2);
        Education education = list.stream().max(Comparator.comparing(o -> o.getEndDate(),
                Comparator.nullsFirst(String::compareTo))).get();
        //StringUtils.isBlank(o.getEndDate()) ? null : o.getEndDate(),
        //为空的排最前面,字符串空排最后面,其他按时间正序
        List<Education> collect = list.stream().sorted(Comparator.comparing(
                (Education e) -> "".equals(e.getEndDate()) ? 1 : 0
            ).thenComparing( (Education o) -> o.getEndDate(),
                Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
        Map<String, Education> collect1 = collect.stream().collect(Collectors.toMap(Education::getEndDate, Function.identity(), (v1, v2) -> v1, LinkedHashMap::new));
//        Map<String, List<Education>> collect2 = collect.stream().collect(Collectors.groupingBy(Education::getEndDate, LinkedHashMap::new, Collectors.toList()));
        if (CollectionUtil.isNotEmpty(collect1) && collect1 != null && education != null) {

        }


    }

    @Test
    public void csRecursion1() {
        List<SchCourseAttendApi> userList = CollUtil.newArrayList();
        userList.add(new SchCourseAttendApi("1", "", ""));
        userList.add(new SchCourseAttendApi("2", "4", ""));
        userList.add(new SchCourseAttendApi("3", "2", ""));
        userList.add(new SchCourseAttendApi("4", "3", ""));
        userList.add(new SchCourseAttendApi(null, "2", ""));
        Map<String, List<SchCourseAttendApi>> collect = userList.stream().collect(Collectors.groupingBy(SchCourseAttendApi::getParentId));
        List<SchCourseAttendApi> childList = CollUtil.newArrayList();
        child(collect, "2", childList, 1, true);
        //递归获取子集(不包含本身
        if (CollectionUtil.isNotEmpty(childList)) {

        }
        Set<String> pr = userList.stream().map(e -> e.getUserId() + "_" + Optional.ofNullable(e.getParentId()).orElse("")).collect(Collectors.toSet());
        for (String s : pr) {
            List<SchCourseAttendApi> weekDou = userList.stream().filter(e -> (e.getUserId() + "_" + Optional.ofNullable(e.getParentId()).orElse("")).equals(s)).collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(weekDou)) {

            }
        }
        

    }

    private void child (Map<String, List<SchCourseAttendApi>> collect,  String id, List<SchCourseAttendApi> childList, Integer level, Boolean bool) {
        List<SchCourseAttendApi> schCourseAttendApis = collect.get(id);
        //限制递归次数
        level +=1;
        if (CollectionUtil.isNotEmpty(schCourseAttendApis) && level < 20) {
            childList.addAll(schCourseAttendApis);
            for (SchCourseAttendApi api : schCourseAttendApis) {
                child(collect, api.getUserId(), childList, level, false);
            }
        }
    }

    @Test
    public void csstr() {
       
        
    }

    @Data
    public static class Education {
        private String schoolName;
        private String majorName;
        private String education;
        private String degree;
        private String startDate;
        private String endDate;
        public Education(String schoolName, String endDate) {
            this.schoolName = schoolName;
            this.endDate = endDate;
        }
    }
    class SchCourseAttendApi {
        String userId;

        public Integer getOrder() {
            return order;
        }

        public void setOrder(Integer order) {
            this.order = order;
        }

        Integer order;

        public Date getCreateTime() {
            return createTime;
        }

        public void setCreateTime(Date createTime) {
            this.createTime = createTime;
        }

        Date createTime;

        @Getter
        @Setter
        String parentId;

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        @Override
        public String toString() {
            return "SchCourseAttendApi{" +
                    "userId='" + userId + '\'' +
                    ", order=" + order +
                    ", createTime=" + createTime +
                    '}';
        }

        SchCourseAttendApi (String userId, Date createTime) {
            this.userId = userId;
            this.createTime = createTime;
        }
        SchCourseAttendApi (String userId, String parentId, String bool) {
            this.userId = userId;
            this.parentId = parentId;
        }

    }

    @Test
    public void hut1() {
        System.out.println(IdUtil.fastSimpleUUID());
        System.out.println(IdUtil.objectId());
        System.out.println(IdUtil.simpleUUID());
        System.out.println(IdUtil.fastUUID());
        System.out.println(IdUtil.getSnowflake(1,1).nextId());
    }
}
